/*
 * @Author: January
 * @Date: 2022-01-03 21:22:07
 */

#include <libecc/cipher/cipher_algs.h>
#include <libecc/cipher/cipher_mode.h>

// block_size
void ctr_process(u8* nonce, int block_size, void* cipher_ctx, _block_cipher cipher_enc, const uint8_t* in, int in_len,uint8_t* out) {
    int i = in_len / block_size;
    int words = block_size / 4;
    uint8_t tmp_buf[MAX_CIPHER_BLOCK_SIZE];
    uint16_t* p_ctr = (uint16_t*)(nonce + 12);
    // 加速异或运算
    uint32_t* out_p4;
    uint32_t* in_p4;

    while(in_len >= block_size) {
        cipher_enc(cipher_ctx, nonce, out);
        (*p_ctr)++;

        in_p4 = (uint32_t*)in;
        out_p4 = (uint32_t*)out;
        for(i=0; i<words; i++) {
            out_p4[i] ^= in_p4[i];
        }
        in_len -= block_size;
        in += block_size;
        out += block_size;
    }

    if (in_len > 0) {
        cipher_enc(cipher_ctx, nonce, tmp_buf);
        (*p_ctr)++;
        for(i=0; i<in_len; i++) {
            out[i] ^= in[i] ^ tmp_buf[i];
        }
    }
}
